/*
 * @Author: @yzcheng
 * @Date: 2021-04-13 15:50:11
 * @Version: 1.0
 * @LastEditors: @yzcheng
 * @Description:
 * @LastEditTime: 2021-04-26 14:30:37
 */

//基础请求路径

const baseURL = '/checc-api/process'

// 请求返回状态码
const codeMessage = {
  200: '服务器成功返回请求的数据。',
  201: '新建或修改数据成功。',
  202: '一个请求已经进入后台排队（异步任务）。',
  204: '删除数据成功。',
  400: '发出的请求有错误，服务器没有进行新建或修改数据的操作。',
  401: '用户没有权限（令牌、用户名、密码错误）。',
  403: '用户得到授权，但是访问是被禁止的。',
  404: '发出的请求针对的是不存在的记录，服务器没有进行操作。',
  406: '请求的格式不可得。',
  410: '请求的资源被永久删除，且不会再得到的。',
  422: '当创建一个对象时，发生一个验证错误。',
  500: '服务器发生错误，请检查服务器。',
  502: '网关错误。',
  503: '服务不可用，服务器暂时过载或维护。',
  504: '网关超时。',
}
const checkStatus = (response) => {
  const { status } = response
  if (status >= 200 && status < 300) {
    return response
  }
  const errortext = codeMessage[response.status] || response.statusText
  const error = new Error(errortext)
  error.name = response.status
  error.response = response
  throw error
}

//格式化参数
const parseQuery = (obj) => {
  let str = ''
  for (let key in obj) {
    const value = typeof obj[key] !== 'string' ? JSON.stringify(obj[key]) : obj[key]
    str += '&' + key + '=' + value
  }
  return str.substr(1)
}

//请求响应后，将response的所有数据转换成json，客户端就可以拿到以json格式响应的所有数据
const parseJSON = (response) => {
  return response.json()
}

const request = (url, params, options) => {
  const { method, headers, formData } = options
  const defaultOptions = {
    // 允许跨域携带资源凭证,发送cookies
    //   - include：无论同源不同源都可以
    //   - same-origin：同源可以，默认值 √
    //   - omit：都拒绝
    credentials: 'include',
    mode: 'cors',
    // 设置请求头
  }
  const token = document.cookie
    ?.split(';')
    ?.filter((item) => item.includes('Authorization'))
    ?.join('')
    ?.split('=')
    ?.pop()
  options.headers = {
    Accept: 'application/json', // 添加携带的数据格式，这个根据需求填写
    Authorization: `Bearer ` + token, //添加鉴权Token
    ...headers, //合并配置项
  }
  if (method === 'GET' && params) {
    url += '?' + parseQuery(params)
  } else if (!formData) {
    // 读取传入的数据格式类型，不是表单数据使用JSON库进行格式化
    options.body = JSON.stringify(params)
  } else {
    options.body = params
  }
  const newOptions = { ...defaultOptions, ...options }

  /**
   * 全部配置好之后，最后使用fetch发起一个请求，它本身需要传入一个url和一个options
   */
  return fetch(baseURL + url, newOptions)
    .then(checkStatus)
    .then(parseJSON)
    .then((data) => data)
    .catch((err) => {
      // 服务器没有响应才会跳转到这里
      if (!window.navigator.onLine) {
        // 断网处理
        // ...
        return
      }
      // 什么都没有，返回一个错误
      return Promise.reject(err)
    })
}

// GET的请求
export async function get(
  url,
  params,
  ownOptions = { method: 'GET', headers: { 'Content-Type': 'application/json; charset=utf-8' } }
) {
  return await request(url, params, ownOptions)
}

// POST请求
export async function post(
  url,
  params = {},
  ownOptions = {
    method: 'POST',
    headers: { 'Content-Type': 'application/json; charset=utf-8' },
    body: {},
  }
) {
  return await request(url, params, ownOptions)
}
// formData
export async function formData(
  url,
  params = {},
  ownOptions = { method: 'POST', headers: {}, body: {}, formData: true }
) {
  return await request(url, params, ownOptions)
}
